﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SolutionExtender.Interfaces;

namespace McTools.SolutionExtender.ParametersPlugin
{
    public partial class ParameterControl : UserControl, IExportControl
    {
        #region Variables

        /// <summary>
        /// Microsoft Dynamics CRM 2011 Organization service
        /// </summary>
        private readonly IOrganizationService _service;

        /// <summary>
        /// Indicates if this control found rules
        /// </summary>
        private bool _hasData;

        #endregion Variables

        #region Constructor

        public ParameterControl(IOrganizationService service)
        {
            InitializeComponent();

            _service = service;
        }

        #endregion Constructor

        private void ParameterControlLoad(object sender, EventArgs e)
        {
            var entities = _service.RetrieveMultiple(new QueryExpression("mctools_parameter")
                {
                    ColumnSet = new ColumnSet("mctools_name",
                                              "mctools_logicalname",
                                              "mctools_valuetype",
                                              "mctools_textvalue",
                                              "mctools_decimalvalue",
                                              "mctools_floatvalue",
                                              "mctools_boolvalue",
                                              "mctools_integervalue",
                                              "mctools_description",
                                              "mctools_memovalue",
                                              "mctools_datevalue",
                                              "mctools_textvalue")
                });

            if(entities.Entities.Count == 0)
            {
                _hasData = false;
                listView1.Visible = false;
                return;
            }

            _hasData = true;

            foreach (var entity in entities.Entities)
            {
                var item = new ListViewItem(entity["mctools_name"].ToString());
                item.SubItems.Add(entity["mctools_logicalname"].ToString());
                item.SubItems.Add(entity.FormattedValues["mctools_valuetype"]);
                item.Tag = entity;

                listView1.Items.Add(item);
            }
        }

        private void ListView1SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                var record = (Entity)listView1.SelectedItems[0].Tag;

                txtName.Text = record["mctools_name"].ToString();
                txtLogicalName.Text = record["mctools_logicalname"].ToString();

                switch (((OptionSetValue) record["mctools_valuetype"]).Value)
                {
                    case 1:
                        textBox1.Text = record["mctools_textvalue"].ToString();
                        textBox1.Visible = true;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                    case 2:
                        textBox1.Text = record["mctools_memovalue"].ToString();
                        textBox1.Visible = true;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                    case 3:
                        rdbTrue.Checked = (bool) record["mctools_boolvalue"];
                        rdbFalse.Checked =! ((bool) record["mctools_boolvalue"]);
                        textBox1.Visible = false;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = true;
                        rdbFalse.Visible = true;
                        break;
                    case 4:
                        textBox1.Text = record["mctools_integervalue"].ToString();
                        textBox1.Visible = true;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                    case 5:
                        textBox1.Text = record["mctools_decimalvalue"].ToString();
                        textBox1.Visible = true;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                    case 6:
                        textBox1.Text = record["mctools_floatvalue"].ToString();
                        textBox1.Visible = true;
                        dtPicker.Visible = false;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                    case 7:
                        dtPicker.Value = (DateTime) record["mctools_datevalue"];
                        textBox1.Visible = false;
                        dtPicker.Visible = true;
                        rdbTrue.Visible = false;
                        rdbFalse.Visible = false;
                        break;
                }
            }
        }

        public XmlNodeList GetSelectedItems()
        {
            if (listView1.SelectedItems.Count == 0 && _hasData)
            {
                pnlError.Visible = true;
                return null;
            }

            pnlError.Visible = false;
            var stringifiedXml = new StringBuilder();
            stringifiedXml.Append("<Root>");

            foreach (ListViewItem item in listView1.SelectedItems)
            {
                var entity = (Entity) item.Tag;
                entity.Id = Guid.Empty;
                entity.Attributes.Remove("mctools_parameterid");

                stringifiedXml.Append(string.Format("<Parameter name=\"{0}\">", entity["mctools_logicalname"]));
                var tempDoc = new XmlDocument();
                tempDoc.LoadXml(BuildReturnedString(entity));

                stringifiedXml.Append(tempDoc.DocumentElement.OuterXml);
                stringifiedXml.Append("</Parameter>");
            }

            stringifiedXml.Append("</Root>");

            var doc = new XmlDocument();
            doc.LoadXml(stringifiedXml.ToString());

            return doc.SelectNodes("Root/Parameter");
        }

        private string BuildReturnedString(Entity entity)
        {
            var mStream = new MemoryStream();
            var serializer = new DataContractSerializer(typeof(Entity),
                                                        null,
                                                        int.MaxValue,
                                                        false,
                                                        false,
                                                        null,
                                                        new KnownTypesResolver());

            var writer = new XmlTextWriter(mStream, Encoding.UTF8)
            {
                Formatting = Formatting.Indented
            };
            serializer.WriteObject(writer, entity);
            writer.Flush();
            mStream.Seek(0, SeekOrigin.Begin);
            var reader = new StreamReader(mStream);
            return reader.ReadToEnd();
        }
    }
}
    